package com.example.order.feign.config;

import feign.RetryableException;
import feign.Retryer;
import lombok.extern.slf4j.Slf4j;

import static java.util.concurrent.TimeUnit.SECONDS;

/**
 * @Author: 唐佳辉
 * @CreateTime： 2025-05-08-10:05
 * @Description: 配置重试机制
 * @Version：1.0
 */

@Slf4j

public class CommonFeignRetry extends Retryer.Default {

    public CommonFeignRetry() {
        // 重试间隔是每次失败之后会等待100毫秒再次发起重试请求的间隔时间
        // 最大间隔时间是每次重试的间隔时间累加起来不能超过这个最大间隔时间，如果超过了就不会在重试，哪怕还没有达到配置的重试次数
        // 重试次数会受最大间隔时间和重试间隔时间影响，如果累计间隔时间超过这个最大间隔时间就不会在重试
        // 重试间隔100毫秒  最大间隔时间1秒  重试5次
        this(100, SECONDS.toMillis(1), 5);
    }

    public CommonFeignRetry(long period, long maxPeriod, int maxAttempts) {
        super(period, maxPeriod, maxAttempts);
    }

    /**
     * 处理或传播重试异常
     * 当发生重试异常时，记录日志并决定是否继续重试或传播异常
     *
     * @param e 重试异常，包含重试的相关信息
     */
    @Override
    public void continueOrPropagate(RetryableException e) {
        // 记录重试异常的日志，提供异常信息以便于问题追踪和定位
        log.warn("【FeignRetryAble】Message【{}】", e.getMessage());
        // 调用父类的方法来决定是继续重试还是传播异常
        super.continueOrPropagate(e);
    }

    /**
     * 克隆重试器
     * 创建并返回一个新的CommonFeignRetry实例，用于在不同的执行线程中共享相同的重试配置
     *
     * @return 新的CommonFeignRetry实例，用于执行重试逻辑
     */
    @Override
    public Retryer clone() {
        // 返回新的CommonFeignRetry实例，确保每个使用该重试器的地方都遵循相同的重试策略
        return new CommonFeignRetry();
    }


}
